package com.adopapa.nezhacloud.authc.controller;

import java.time.Instant;
import java.util.Map;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.adopapa.nezhacloud.authc.domain.DepartmentInfo;
import com.adopapa.nezhacloud.authc.domain.UserInfo;
import com.adopapa.nezhacloud.authc.service.DepartmentInfoService;
import com.adopapa.nezhacloud.authc.service.UserInfoService;
import com.adopapa.nezhacloud.common.RestResponse;
import com.adopapa.nezhacloud.common.Tools;
import com.adopapa.nezhacloud.ddd.codegen.SqlGen;
import com.adopapa.nezhacloud.ddd.conf.AppConstants;
import com.adopapa.nezhacloud.ddd.controller.BaseController;

@RestController
@RequestMapping("/authc/userinfo")
public class UserInfoController extends BaseController {

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private DepartmentInfoService departmentInfoService;

    @SqlGen(name = {"权限管理", "用户管理", "分页查询"}, method = SqlGen.METHOD_GET, path = "/userinfos/{pageNo}")
    @GetMapping(path = "/userinfos/{pageNo}", produces = MediaType.APPLICATION_JSON_VALUE)
    public RestResponse getUserInfoPage(@RequestHeader String authorization, //
                                        @PathVariable Integer pageNo, //
                                        @RequestParam(required = false) String loginName, //
                                        @RequestParam(required = false) String userName, //
                                        @RequestParam(required = false) String createTime, //
                                        @RequestParam(required = false) String createTime2, //
                                        @RequestParam(required = false) Integer pageSize) {

        UserInfo userInfo = new UserInfo();

        userInfo.setLoginName(loginName);
        userInfo.setUserName(userName);
        Instant createTimeInstant = Tools.fromTimeStr(createTime);
        userInfo.setCreateTime(createTimeInstant);
        Instant createTime2Instant = Tools.fromTimeStr(createTime2);
        userInfo.setCreateTime2(createTime2Instant);

        pageSize = Tools.empty(pageSize) ? AppConstants.DEFAULT_PAGE_SIZE : pageSize;

        Page<UserInfo> page = userInfoService.getUserInfoPage(pageNo, pageSize, userInfo);

        return RestResponse.ok(page);
    }

    @SqlGen(name = {"权限管理", "用户管理", "单个查询"}, method = SqlGen.METHOD_GET, path = "/userinfo/{id}")
    @GetMapping(path = "/userinfo/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public RestResponse getHappyDemo(@RequestHeader String authorization, //
                                     @PathVariable String id) {
        UserInfo userInfo = userInfoService.getUserInfoById(id);
        return RestResponse.ok(userInfo);
    }

    @SqlGen(name = {"权限管理", "用户管理", "编辑信息"}, method = SqlGen.METHOD_POST, path = "/userinfos")
    @PostMapping(path = "/userinfos", produces = MediaType.APPLICATION_JSON_VALUE, //
            consumes = MediaType.APPLICATION_JSON_VALUE)
    public RestResponse saveUserInfo(@RequestHeader String authorization, //
                                     @RequestBody Map<String, Object> params) {

        String id = getMapValue(params, "id", String.class);

        String loginName = getMapValue(params, "loginName", String.class);
        String loginPwd = getMapValue(params, "loginPwd", String.class);
        String userName = getMapValue(params, "userName", String.class);
        String remark = getMapValue(params, "remark", String.class);
        String deptId = getMapValue(params, "deptId", null);

        if (Tools.empty(loginName)) {
            throw new RuntimeException("用户名称不能为空");
        }
        if (Tools.empty(loginPwd)) {
            throw new RuntimeException("用户密码不能为空");
        }
        if (Tools.empty(userName)) {
            throw new RuntimeException("姓名不能为空");
        }
        if (Tools.empty(deptId)) {
            throw new RuntimeException("组织ID不能为空");
        }

        DepartmentInfo departmentInfo = departmentInfoService.getDepartmentInfoById(deptId);
        if (Tools.empty(departmentInfo)) {
            throw new RuntimeException("指定组织ID对应信息不存在");
        }

        UserInfo userInfo = null;
        if (Tools.empty(id)) {
            userInfo = new UserInfo();
            userInfo.setCreateTime(Instant.now());
        } else {
            userInfo = userInfoService.getUserInfoById(id);
            if (Tools.empty(userInfo)) {
                throw new RuntimeException("指定id对应信息不存在");
            }
        }
        UserInfo existed = userInfoService.getUserInfoByLoginName(loginName);
        if (!Tools.empty(existed) && !existed.getId().equals(id)) {
            throw new RuntimeException("loginName已经存在");
        }

        userInfo.setLoginName(loginName);
        userInfo.setLoginPwd(passwordEncoder.encode(loginPwd));
        userInfo.setUserName(userName);
        userInfo.setRemark(remark);
        userInfo.setDepartmentInfo(departmentInfo);

        userInfoService.saveUserInfo(userInfo);

        return RestResponse.ok();

    }

    @SqlGen(name = {"权限管理", "用户管理", "删除信息"}, method = SqlGen.METHOD_DELETE, path = "/userinfo/{id}")
    @DeleteMapping(path = "/userinfo/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    public RestResponse deleteUserInfo(@RequestHeader String authorization, //
                                       @PathVariable String id) {
        try {
            userInfoService.deleteUserInfo(id);
        } catch (Exception e) {
            logger.error(ExceptionUtils.getStackTrace(e));
        }

        return RestResponse.ok();
    }

}
